package com.chenwc.util.fileutil.propertiesfile;

import com.chenwc.enumeration.TranslateSoftware;
import com.chenwc.util.LoadTerminology;
import com.chenwc.util.Util;
import com.chenwc.util.translate.youdao.BatchTranslateByYouDaoUtil;
import com.chenwc.util.translate.youdao.enumeration.YouDaoLang;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * properties 文件工具
 *
 * @author chenwc
 * @package com.chenwc.util.fileutil.propertiesfile
 * @project wso2-sinicization
 * @date 2024/5/25
 */
public class PropertiesFileUtil {

    private static final Logger log = LoggerFactory.getLogger(PropertiesFileUtil.class);

    /**
     * 批量文本翻译每次翻译文本条数
     */
    private static final Integer PER_BATCH_COUNT = 50;

    /**
     * 写入属性文件
     */
    public static void storePropertiesFile(Properties properties, String pathAndFileName) {

        File file = new File(pathAndFileName);
        log.info("写入文件路径: {}", file.getAbsolutePath());

        Writer writer = null;
        try {
            FileUtils.touch(file);
            writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            properties.store(writer, "file update...");
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            log.error("Error occurred: ", e);
        } finally {
            try {
                if (null != writer) {
                    writer.close();
                }
            } catch (Exception e2) {
                // TODO: handle exception
                log.error("Error occurred: ", e2);
            }
        }
    }

    /**
     * 使用有道智云批量文本翻译api属性文件
     *
     * @param propertiesFilePath            需要翻译的属性文件路径
     * @param savePropertiesFilePathAndName 翻译后的属性文件保存路径和文件名
     */
    public static void translatePropertiesFileByBatchYouDao(String propertiesFilePath, String savePropertiesFilePathAndName) {
        Properties properties = new Properties();
        File file = new File(propertiesFilePath);
        FileInputStream fileInputStream = null;
        Map<String, String> localTerminology = LoadTerminology.getTerminology();
        try {
            fileInputStream = new FileInputStream(file);
            properties.load(fileInputStream);
            List<String> qStr = new ArrayList<>();
            int index = 0, count = 0;
            int size = 0;
            //先查出所有值非空的个数
            for (String key : properties.stringPropertyNames()) {
                String value = properties.getProperty(key);
                if (StringUtils.isNotEmpty(value)) {
                    size++;
                }
            }
            for (String key : properties.stringPropertyNames()) {
                String value = properties.getProperty(key);
                if (StringUtils.isNotEmpty(value)) {
                    index++;
                    qStr.add(value);
                    //如果有 BATCH_COUNT 条记录时，则批量执行一次
                    if (index % PER_BATCH_COUNT == 0) {
                        count++;
                        log.info("每 {} 条批量执行批量翻译一次", PER_BATCH_COUNT);
                        //批量执行
                        Map<String, String> ret;
                        try {
                            ret = BatchTranslateByYouDaoUtil.translate(qStr, YouDaoLang.ENGLISH, YouDaoLang.CHINESE);
                        } catch (Exception e) {
                            Thread.sleep(5000);
                            ret = BatchTranslateByYouDaoUtil.translate(qStr, YouDaoLang.ENGLISH, YouDaoLang.CHINESE);
                        }
                        for (String key2 : properties.stringPropertyNames()) {
                            String value2 = properties.getProperty(key2);
                            if (StringUtils.isNotEmpty(value2) && ret.containsKey(value2)) {
                                if (localTerminology.containsKey(key2.toLowerCase())) {
                                    properties.put(key2, localTerminology.get(key2.toLowerCase()));
                                } else {
                                    properties.put(key2, ret.get(value2));
                                }
                            }
                        }
                        qStr.clear();
                        Thread.sleep(1000);
                    }
                }
            }
            // 总条数不是批量数值的整数倍需要再额外的执行一次
            if (size % PER_BATCH_COUNT != 0) {
                log.info("剩余未执行 {} 条批量执行一次", size - count * PER_BATCH_COUNT);
                //批量执行
                //批量执行
                Map<String, String> ret;
                try {
                    ret = BatchTranslateByYouDaoUtil.translate(qStr, YouDaoLang.ENGLISH, YouDaoLang.CHINESE);
                } catch (Exception e) {
                    Thread.sleep(5000);
                    ret = BatchTranslateByYouDaoUtil.translate(qStr, YouDaoLang.ENGLISH, YouDaoLang.CHINESE);
                }
                for (String key2 : properties.stringPropertyNames()) {
                    String value2 = properties.getProperty(key2);
                    if (StringUtils.isNotEmpty(value2) && ret.containsKey(value2)) {
                        if (localTerminology.containsKey(key2.toLowerCase())) {
                            properties.put(key2, localTerminology.get(key2.toLowerCase()));
                        } else {
                            properties.put(key2, ret.get(value2));
                        }
                    }
                }
            }
            storePropertiesFile(properties, savePropertiesFilePathAndName);
        } catch (Exception e) {
            log.error("Error occurred: ", e);
        } finally {
            if (null != fileInputStream) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    log.error("Error occurred: ", e);
                }
            }
        }
    }

    /**
     * 翻译属性文件
     *
     * @param propertiesFilePath            需要翻译的属性文件路径
     * @param savePropertiesFilePathAndName 翻译后的属性文件保存路径和文件名
     * @param translateSoftware             翻译软件
     */
    public static void translatePropertiesFile(String propertiesFilePath, String savePropertiesFilePathAndName, TranslateSoftware translateSoftware) {
        Properties properties = new Properties();
        File file = new File(propertiesFilePath);
        FileInputStream fileInputStream = null;
        HashMap<String, String> terminology = LoadTerminology.getTerminology();
        try {
            fileInputStream = new FileInputStream(file);
            properties.load(fileInputStream);
            for (String key : properties.stringPropertyNames()) {
                String value = properties.getProperty(key);
                log.info("key-->" + key + "    value-->" + value);
                String cntext = null;
                if (terminology.containsKey(value.toLowerCase())) {
                    cntext = terminology.get(value.toLowerCase());
                } else {
                    try {
                        if (!Util.isEmpty(value)) {
                            cntext = Util.getValueByTranslateSoftware(value, translateSoftware);
                        }
                        // Thread.sleep(1000);
                    } catch (Exception e) {
                        // TODO: handle exception
                        log.error(e.getMessage());
                        Thread.sleep(20000);
                        if (!Util.isEmpty(value)) {
                            cntext = Util.getValueByTranslateSoftware(value, translateSoftware);
                        }
                    }
                }
                log.info("key-->" + key + "    value-->" + cntext);
                if (Util.isEmpty(cntext)) {
                    properties.put(key, "");
                } else {
                    properties.put(key, Util.valueReplace(cntext));
                }
                Thread.sleep(10);
            }
            storePropertiesFile(properties, savePropertiesFilePathAndName);
        } catch (Exception e) {
            log.error("Error occurred: ", e);
        } finally {
            if (null != fileInputStream) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    log.error("Error occurred: ", e);
                }
            }
        }
    }
}
